package com.baidu.camera.usbcamera;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.hardware.usb.UsbDevice;
import android.widget.Toast;

import com.baidu.camera.R;
import com.baidu.camera.utils.FileUtils;
import com.baidu.camera.utils.ToastUtils;
import com.serenegiant.usb.CameraDialog;
import com.serenegiant.usb.DeviceFilter;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.UVCCamera;

import java.io.FileOutputStream;
import java.util.List;

/**
 * Created by JGW-android on 2016/3/11.
 */
public class USBCameraHelper {
    private USBMonitor mUSBMonitor;
    private UVCCamera mCamera;
    private List<DeviceFilter> mFilter;
    private UVCCameraTextureView mCameraView;
    private Context context;

    //init camera related
    public void initCamera(Context context, UVCCameraTextureView mCameraView) {
        this.context = context;
        this.mCameraView = mCameraView;
        mUSBMonitor = new USBMonitor(context, mOnDeviceConnectListener);//init usb monitor
        mUSBMonitor.register();
        mFilter = DeviceFilter.getDeviceFilters(context, R.xml.device_filter);
        mCameraView.setCallback(mCallback);
    }

    public static USBCameraHelper createUsbCameraHelper() {
        return new USBCameraHelper();
    }

    private USBCameraHelper() {
    }

    private final USBMonitor.OnDeviceConnectListener mOnDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() {
        @Override
        public void onAttach(final UsbDevice device) {
            Toast.makeText(context, R.string.usbattached, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onConnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock, final boolean createNew) {
            initCamera(ctrlBlock);
            startPreview();
        }

        @Override
        public void onDisconnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock) {
            closeCamera();
        }

        @Override
        public void onDettach(final UsbDevice device) {
            Toast.makeText(context, R.string.usbdetached, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel() {
        }
    };


    private final CameraViewInterface.Callback mCallback = new CameraViewInterface.Callback() {
        @Override
        public void onSurfaceCreated() {

            if (!mUSBMonitor.isRegistered()) return;
            //Try to start camera
            final List<UsbDevice> list = mUSBMonitor.getDeviceList(mFilter.get(0));
            if (list.size() > 0) {
                UsbDevice device = list.get(0);
                ToastUtils.simpleToast(context, device.getDeviceName());
                if (mUSBMonitor.hasPermission(device)) {
                    USBMonitor.UsbControlBlock ctrlBlock = new USBMonitor.UsbControlBlock(mUSBMonitor, device);
                    initCamera(ctrlBlock);
                    startPreview();
                } else {
                    mUSBMonitor.requestPermission(device);
                }
            } else {
                CameraDialog.showDialog((Activity) context);
            }
        }

    };


    //close camera
    private void closeCamera() {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.destroy();
            mCamera = null;
        }
    }


    //init open preview
    private void startPreview() {
        SurfaceTexture st = mCameraView.getSurfaceTexture();
//        if (mSurface != null) mSurface.release();
//        mSurface = new Surface(st);
        if (mCamera != null) {
            //mCamera.setPreviewSize(200, 200, UVCCamera.FRAME_FORMAT_MJPEG);
            //mCamera.setPreviewDisplay(mSurface);
            mCamera.setPreviewTexture(st);
            mCamera.startPreview();
        }
    }

    //init camera
    private void initCamera(USBMonitor.UsbControlBlock ctrlBlock) {
        mCamera = new UVCCamera();
        mCamera.open(ctrlBlock);
    }

    //capture picture
    public void captureImage(String path) {
        if (mCameraView == null) return;
        Bitmap bitmap = Bitmap.createBitmap(mCameraView.getBitmap());
        try {
            FileOutputStream fos = new FileOutputStream(FileUtils.createImageFile(path));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
            ToastUtils.simpleToast(context, "store successfully");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // register usb monitor
    public void onResume() {
        if (mCameraView == null || mUSBMonitor == null) return;
        mUSBMonitor.register();
        mCameraView.onResume();
    }

    //unregister usb monitor and destroy camera
    public void onPause() {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.destroy();
        }
        if (mCameraView == null || mUSBMonitor == null) return;
        mCameraView.onPause();
        mUSBMonitor.unregister();

    }

    // unregister monitor
    public void onDestroy() {
        if (mUSBMonitor != null) mUSBMonitor.destroy();
        mCameraView = null;
    }


}
